﻿namespace LogManager.Core.Models
{
    using LogManager.Core.Helpers;
    using LogManager.Utils.Unity;
    using LogManager.Utils.Xml;
    using System;
    using System.Collections.ObjectModel;
    using System.Collections.Specialized;
    using System.Linq;
    using System.Xml.Linq;
    using LogManager.Core.Factories;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class Server : XmlElementBase, IServer
    {
        public const string DEFAULT_TEMPLATE = @"<Server Name=""DEV-SERVER"" Ip=""Network IP or Name"" RetentionHours=""40"">" + Location.DEFAULT_TEMPLATE + "</Server>";

        public virtual string Name { get; set; }
        public virtual string Ip { get; set; }

        [DependsUpon("RetentionHours")]
        public TimeSpan RetentionDuration { get; private set; }

        private int _retentionHours;
        public virtual int RetentionHours
        {
            get { return _retentionHours; }
            set
            {
                _retentionHours = value;
                RetentionDuration = TimeSpan.FromHours(RetentionHours);
            }
        }

        public virtual IPlateform ParentPlateform { get; protected set; }
        public ObservableCollection<ILocation> Locations { get; private set; }
        public readonly IXmlElementFactory _xmlElementFactory;

        public Server(XElement baseNode, IPlateform parent, IXmlElementFactory factory)
            : base(baseNode)
        {
            this._xmlElementFactory = factory;
            this.ParentPlateform = parent;
            this.Initialize();
            this.PropertyChanged += (a, b) => SaveChanges();
            this.Locations.CollectionChanged += (a, b) => SaveChanges();
        }

        private void Initialize()
        {
            var xml = new XmlResolver<Server>(this.BaseNode);
            this.Name = xml.GetAttributeValue(c => c.Name);
            this.Ip = xml.GetAttributeValue(c => c.Ip);
            this.RetentionHours = xml.GetAttributeValue(c => c.RetentionHours);
            this.Locations = new ObservableCollection<ILocation>(xml.ResolveChildren(c => c.Locations, xElm => this._xmlElementFactory.CreateLocation(xElm, this)));
        }

        public override void SaveChanges()
        {
            var xml = new XmlResolver<Server>(BaseNode);
            xml.SetAttributeValue(c => c.Name, Name);
            xml.SetAttributeValue(c => c.Ip, Ip);
            xml.SetAttributeValue(c => c.RetentionHours, RetentionHours);
            xml.SetChildren(c => c.Locations, Locations.OfType<IXmlElement>());
        }

        public void DeleteServer()
        {
            this.ParentPlateform.Servers.Remove(this);
        }

        public ILocation AddNewLocation()
        {
            var instance = this._xmlElementFactory.CreateNewLocation(this);
            this.Locations.Add(instance);
            return instance;
        }
    }
}
